iT邦幫忙

2025 iThome 鐵人賽

DAY 5
0
Software Development

從零開始Pandas-外加一點Matplotlib系列 第 5

Day4: 基於Series的操作及缺失值處理

  • 分享至 

  • xImage
  •  

昨天介紹了欄位的新增修改,明天打算介紹條件篩選。在進入條件篩選之前,先插個花介紹一些基於series的常用操作。

抓出N筆資料

  • head(N) 列出前面N筆資料
  • tail(N) 列出最後N筆資料
  • sample(N) 隨機抓出N筆資料
df = pd.DataFrame({"name":["Mary", "John", "Cindy", "Ken", "Zoe", "Taylor"], 
                   "salary":[50000,72000,89000,63000,109000, 150000], 
                   })

df["annual_salary"] = df["salary"] *14
df["department"] = "Sales Dept"

first_record = df["annual_salary"].head(3)
last_record = df["annual_salary"].tail()
random_data = df["annual_salary"].sample(3)

如果括號裡沒有給值的話,head/tail預設會是前5筆或後5筆,sample只會回傳1筆。

about 統計函數

如果你的series內容是數值,可以很方便的使用這些統計運算方法。

  • min 最小值

  • max 最大值

  • mean 平均值

  • median 中位數

  • std 標準差

  • describe 統計數據大禮包
    回傳一組包含筆數、最大值、最小值、平均值、中位數、標準差、四分位數的series

  • quantile 數值的分位數
    可以是0-1中間的一個數字,也可以是一個串列, 若為串列回傳series
    如果給非0-1之間的數字會報錯

  • sum 加總

  • diff 與前個數字的差, 回傳series

    salary.min()
    salary.max()
    salary.mean()
    salary.median()
    salary.sum()
    salary.describe()
    salary.quantile([.2, .3, .9, 1])
    salary.diff()
    
    Result:
    
    MIN: 700000
    MAX: 2100000
    MEAN: 1243666.6666666667
    MEDIAN: 1127000.0
    SUM: 533000
    
    DESCRIBE:
    count    6.000000e+00
    mean     1.243667e+06
    std      5.089085e+05
    min      7.000000e+05
    25%      9.135000e+05
    50%      1.127000e+06
    75%      1.456000e+06
    max      2.100000e+06
    Name: annual_salary, dtype: float64
    
    QUANTILE: 
    0.2     882000.0
    0.3     945000.0
    0.9    1813000.0
    1.0    2100000.0
    
    DIFF:
    0        NaN
    1    22000.0
    2    17000.0
    3   -26000.0
    4    46000.0
    5    41000.0
    

    如果series內容是文字,還是可以用min, max 和describe,min/max會用文字排序。
    describe回傳結果會與數值不同

    count       7  #總筆數
    unique      5  #去掉重複以後的筆數
    top       Ken  #最高頻出現的內容值
    freq        3  #最高頻出現的筆數
    

about 缺失值 (NA值)

使用過db和csv/excel的人想必都和NA、None、#N/A交手過,Pandas處理缺失值so ez,絕對能帶給你千年傳統全新感受。 這撲面而來的年代感。

首先我們要先建一個裡面有None值的DataFrame

df = pd.DataFrame(
    {"name":pd.Series(["Mary", "John", "Cindy", "Ken", "Zoe", "Taylor", "Amy"]), 
     "salary":pd.Series([50000, 72000, None, 63000, 109000, 150000])
    })

這個series salary會產生兩個NA值,一個是塞給它的None,另一個是series name有7個值,但salary只有6個,為了對齊欄位name資料長度而長出來最後的NA。
https://ithelp.ithome.com.tw/upload/images/20250918/20178631HVTbHZDEkD.png

再來就可以快樂的使用na方法了

isna 判斷每個data是否為na值

回傳一個長度一致的series,若是對應索引是缺失值則為TRUE,非缺失值對應索引為FALSE
打字看起來有點繁瑣,可以看下面表格的結果較為直觀。

notna 判斷每個data是否不為na值

回傳一個長度一致的series,若是對應索引是缺失值則為FALSE,非缺失值對應索引為TRUE

hasnans 判斷整個series中是否存在na值

回傳true/false

df["salary"].isna()     #回傳series
df["salary"].notna()    #回傳series
df["salary"].hasnans()  #回傳bool

結果如下

index df['salary'] isna() notna()
0 50000 False True
1 72000 False True
2 NaN True False
3 63000 False True
4 109000 False True
5 150000 False True
6 NaN True False

我們也可以加碼用methond chaining

  1. 加上sum()去計算缺失值的個數
    邏輯是這樣的,因為isna()/notna()回傳的是一個true/false組成的布林陣列,false為0,true為1,用sum()去加總就能得到缺失值的個數。
  2. 加上mean()去計算缺失值在該欄位的佔比
    round是四捨五入到小數3位
df["salary"].isna().sum()
df["salary"].isna().mean().round(3)

dropna 刪除na值

dropna的用法很靈活,可以只要有na的欄位全刪,也可以是指定欄位,也可以給一個保留列的閾值門檻。這個thresh在說明文件是這麼寫的

Keep only the rows with at least 2 non-NA values.

df.dropna()                               # 刪掉有na的列
df.dropna(axis=1)                         # 刪掉有na的欄
df.dropna(how='all')                      # 刪除全空的列
df.dropna(axis=1, how="all")              # 刪除全空的欄
df.dropna(subset=["name", "price"])       # 僅檢查特定欄
df.dropna(thresh=2)                       # 至少要有2個非缺失才保留該列

補充一下 axis,很多方法都有axis屬性 0代表列(row),1代表欄(column) 一般的行為預設都會是0,所以以下這兩個行為會是一樣的。

df.dropna(how='all')
df.dropna(axis=0, how="all")

之所以說一般行為預設都會是0,就代表凡事總有例外,drop_duplicates的axis預設會是1,但這個以後再分享~

fillna(0) 填補na值

直接上範例

df["salary"] = df["salary"].fillna(0)                      # 如果是na值就塞0
df["salary"] = df["salary"].fillna(df["salary"].median())  # 如果是na值就塞中位數

about 內容值的操作

  • any 檢查串列中是否有 True
  • all 檢查串列中是否都是 True
  • size 計算series的元素個數
  • shape 回傳每個軸 (axis)的筆數
  • unique 資料去重複
  • value_counts 統計每個資料出現的次數
df = pd.DataFrame(
    {"name":pd.Series(["Mary", "John", "Cindy", "Mary", "Zoe", "Taylor", "Mary"]), 
     "salary":pd.Series([50000, 72000, None, 63000, 109000, 150000])})

df["name"].unique()
df["name"].value_counts()

結果:
unique: ['Mary' 'John' 'Cindy' 'Zoe' 'Taylor']
value_counts:

name count
Mary 3
John 1
Cindy 1
Zoe 1
Taylor 1
  • nsmallest(n) 取得最小的N筆資料
  • nlargest(n) 取得最大的N筆資料
s = pd.Series(np.random.rand(10))
s.nsmallest(3)
s.nlargest(5)

今天的內容有點零散,是為了因應明天的重點戲
就是最常用的資料過濾啦~


上一篇
Day3: 欄位異動的操作
系列文
從零開始Pandas-外加一點Matplotlib5
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言